#ifndef TCP_SOCKET_H
#define TCP_SOCKET_H

class InetAddress;

struct tcp_info;

class Socket {
public:
    explicit Socket(int sockfd) : sockfd_(sockfd) {}

    ~Socket();

    /**
     * 获取维护的socket文件描述符
     * @return
     */
    int fd() const { return sockfd_; }

    // return true if success.
    bool getTcpInfo(struct tcp_info *) const;

    bool getTcpInfoString(char *buf, int len) const;

    /* socket 基本的bind, listen和accept的封装 */
    void bindAddress(const InetAddress &addr);

    void listen();

    int accept(InetAddress *peeraddr);

    /**
     * 关闭当前socket的写入端口
     */
    void shutdownWrite();

    /**
     * 关闭 / 开启Nagle算法, 关闭Nagle会进入降低网络包的延迟
     * @param on
     */
    void setTcpNoDelay(bool on);

    ///
    /// Enable/disable SO_REUSEADDR
    ///
    void setReuseAddr(bool on);

    ///
    /// Enable/disable SO_REUSEPORT
    ///
    void setReusePort(bool on);

    /**
     * 开启 / 关闭 Tcp_cork, 这个选项会让网络包延迟发送
     */
    void setKeepAlive(bool on);

    // FIXME: 暂时继续使用
    /**
     * 用于获取socket文件描述符在本地保存的地址信息
     * @param sockfd 要获取的文件描述符的地址信息
     * @return
     */
    static struct sockaddr_in getLocalAddr(int sockfd);

    /**
     * 将连接到socket的对等方的地址信息存放起来
     * @param sockfd
     * @return
     */
    static struct sockaddr_in getPeerAddr(int sockfd);

private:
    const int sockfd_;
};

#endif //TCP_SOCKET_H
